package interfacegraphique;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;

import tools.Format;
import bbqtorrent.InvalidBEncodingException;
import bbqtorrent.Torrent;
import bbqtorrent.TorrentManager;

/**
 *
 * @author CYRIL
 */
public class FenetrePrincipale extends JFrame {

    private JFileChooser fc;
    /********** Table *************/
    private String title[] = {"Titre", "Progression", "DL Speed", "UL Speed", "Taille"} ;
    private Object data[][] = {};
    private DefaultTableModel model;
    private JTable table;
   
    /********** MenuBar *************/
    private JMenuBar menuBar;
    private JMenu fichier;
    private JMenuItem ouvrir;
    private JMenuItem ouvrirURL;
    private JMenuItem nouveau;
    private JMenu action;
    private JMenuItem stopAll;
    private JMenuItem clear;
    /********** ToolBar *************/
    private JToolBar toolbar;
    private ClassLoader classLoader;
    private URL imAdd;
    private JButton add;
    private URL imAddUrl;
    private JButton addUrl;
    private URL imCreate;
    private JButton create;
    /********** PanelInfo *************/
    private JPanel info;
    private JLabel dlSpeed;
    private JLabel upSpeed;
    /********** Torrent **************/    
	private TorrentManager torrentManager;

    public FenetrePrincipale() {
    	try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

        this.setTitle("BbqTorrent");
        this.setSize(600, 300);

        this.initMenu();
        this.initToolBar();
        this.initTable();
        this.initInfo();
        this.setIconImage(new ImageIcon(classLoader.getResource("images/bbq.png")).getImage());
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
    }

    private void initMenu() {

        this.fc = new JFileChooser();
        this.menuBar = new JMenuBar();
        this.fichier = new JMenu("Fichier");
        this.ouvrir = new JMenuItem("Ouvrir un fichier");
        this.ouvrirURL = new JMenuItem("Ajouter un fichier distant");
        this.nouveau = new JMenuItem("Créer");
        this.action = new JMenu("Action");
        this.stopAll = new JMenuItem("Tout arrêter");
        this.clear = new JMenuItem("Effacer");        
        
        this.torrentManager = new TorrentManager();
        
        this.ouvrir.addActionListener(new OpenListener());
        this.ouvrirURL.addActionListener(new OpenURLListener());
        this.nouveau.addActionListener(new CreateListener());
        

        this.fichier.add(ouvrir);
        this.fichier.add(ouvrirURL);
        this.fichier.add(nouveau);
        this.menuBar.add(fichier);

        this.action.add(stopAll);
        this.action.add(clear);
        this.menuBar.add(action);

        this.setJMenuBar(menuBar);
    }

    private void initToolBar() {

        this.toolbar = new JToolBar();
        this.classLoader = getClass().getClassLoader();
        this.imAdd = this.classLoader.getResource("images/add.png");
        this.add = new JButton(new ImageIcon(this.imAdd));
        this.imAddUrl = this.classLoader.getResource("images/addUrl.png");
        this.addUrl = new JButton (new ImageIcon(this.imAddUrl));
        this.imCreate = this.classLoader.getResource("images/create.png");
        this.create = new JButton (new ImageIcon(this.imCreate));

        this.add.addActionListener(new OpenListener());
        this.addUrl.addActionListener(new OpenURLListener());
        this.create.addActionListener(new CreateListener());

        this.add.setToolTipText("Ouvrir un fichier");
        this.add.setBorder(null);
        this.add.setContentAreaFilled(false);
        this.addUrl.setToolTipText("Ouvrir un fichier distant");
        this.addUrl.setBorder(null);
        this.addUrl.setContentAreaFilled(false);
        this.create.setToolTipText("Créer un torrent");
        this.create.setBorder(null);
        this.create.setContentAreaFilled(false);

        this.toolbar.add(add);
        this.toolbar.add(addUrl);
        this.toolbar.add(create);
        this.toolbar.setFloatable(false);
        this.getContentPane().add(toolbar, BorderLayout.NORTH);

    }

    private void initTable() {

        this.model = new DefaultTableModel(this.data, this.title){
            public boolean isCellEditable(int row, int col) {
                return false;
            }
        };
        this.table = new JTable(this.model);

        this.table.getColumn(title[1]).setCellRenderer(new ProgressRenderer());
        this.table.setRowHeight(40);
        this.table.setRowSorter(new TableRowSorter(this.model));
        this.table.addMouseListener(new MouseAdapter() {

            public void mouseReleased(MouseEvent event) {
                if (event.getButton() == event.BUTTON3) {
                    if (FenetrePrincipale.this.table.columnAtPoint(new Point(event.getX(), event.getY())) != -1) {

                        JMenuItem delete = new JMenuItem("Supprimer");
                        JMenuItem stop = new JMenuItem("Arrêter");
                        JMenuItem property = new JMenuItem("Propriétés");

                        delete.addActionListener(new DeleteListener(new Point(event.getX(), event.getY())));
                        property.addActionListener(new PropertyListener(new Point(event.getX(), event.getY())));
                        stop.addActionListener(new StopListener(new Point(event.getX(), event.getY())));
                        
                        JPopupMenu menu = new JPopupMenu();
                        menu.add(delete);
                        menu.add(stop);
                        menu.add(property);
                        menu.show(FenetrePrincipale.this.table, event.getX(), event.getY());
                    }
                }
            }
        });
        
        this.getContentPane().add(new JScrollPane(this.table), BorderLayout.CENTER);
        //this.table.setDefaultRenderer(Object.class, new JTableRender());
    }
    
    private void initInfo() {

        this.info = new JPanel();
        this.dlSpeed = new JLabel();
        this.upSpeed = new JLabel();

        this.info.setLayout(new FlowLayout());
        this.dlSpeed.setText("DL : 0.0 ko/s");
        this.upSpeed.setText("UP : 0.0 ko/s");

        this.info.add(dlSpeed);
        this.info.add(upSpeed);

        this.getContentPane().add(info, BorderLayout.SOUTH);
    }

    class DeleteListener implements ActionListener {

        private Point point = null;

        public DeleteListener(Point p) {
            this.point = p;
        }

        public void actionPerformed(ActionEvent e) {
            int row = table.rowAtPoint(point);
            FenetrePrincipale.this.model.removeRow(row);
        }
    }

    class PropertyListener implements ActionListener {

        private Point point = null;

        public PropertyListener(Point p) {
            this.point = p;
        }

        public void actionPerformed(ActionEvent e) {
            int row = table.rowAtPoint(point);            
            Torrent torrent = FenetrePrincipale.this.torrentManager.find((String) ((DefaultTableModel) table.getModel()).getValueAt(row, 0));
            FenetreProperty prop = new FenetreProperty(torrent);
        }
    }



    class OpenListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            fc.setDialogTitle("Ouvrir");
            fc.setApproveButtonText("Ouvrir");
            int returnVal = fc.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {                
				try {					
					if (fc.getSelectedFile().getName().endsWith(".torrent")) {
	                    //Ajoute un objet Torrent dans le panel
						FenetrePrincipale.this.addTorrent(fc.getSelectedFile());	                  
	                } else {

	                    MessageErreur me = new MessageErreur("Ce n'est pas un fichier torrent");
	                    me.setLocationRelativeTo(FenetrePrincipale.this.getContentPane());

	                }
				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (InvalidBEncodingException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
                
            }
        }
    }

    class OpenURLListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            FenetreAddUrl url = new FenetreAddUrl(FenetrePrincipale.this);
            url.setLocationRelativeTo(FenetrePrincipale.this.getContentPane());
        }
    }
    class StopListener implements ActionListener {
    	private Point point = null;
    	private DefaultTableCellRenderer rend = new DefaultTableCellRenderer();

        public StopListener(Point p) {
            this.point = p;
        }

        public void actionPerformed(ActionEvent e) {
            int row = table.rowAtPoint(point);
            /*Torrent t = null;
            for (int i=0; i<FenetrePrincipale.this.listeTorrent.size(); i++){
				if (FenetrePrincipale.this.listeTorrent.get(i).getName().equals((String) ((DefaultTableModel) table.getModel()).getValueAt(row, 0)))
            		t = FenetrePrincipale.this.listeTorrent.get(i);
            }*/
            
        }
    }
    class CreateListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            Object donnee[] = {"Titre", 50, "Download Vitesse", "Upload Vitesse", "Taille"};
            FenetrePrincipale.this.model.addRow(donnee);
        }
    }

    class ProgressRenderer extends DefaultTableCellRenderer {
        private final JProgressBar b = new JProgressBar(0, 100);
    public ProgressRenderer() {
        super();
        setOpaque(true);
        b.setBorder(BorderFactory.createEmptyBorder(1,1,1,1));
    }
    @Override public Component getTableCellRendererComponent(JTable table, Object value,
                                                   boolean isSelected, boolean hasFocus,
                                                   int row, int column) {
        Integer i = (Integer)value;
        String text = "Fait";
        if(i<0) {
            text = "Annulé";
        }else if(i<100) {
            b.setValue(i);
            return b;
        }
        super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column);
        return this;
    }
    }
    
    private void displayTorrent(Torrent torrent) {
    	System.out.println(torrent);
		
		double size = (double) torrent.getLength();				
		Object[] t = {torrent.getName(),0,"0","0",Format.bytes(size)};
		FenetrePrincipale.this.model.addRow(t);     
    }
    
    public void addTorrent(File file) throws InvalidBEncodingException, IOException{
			Torrent torrent = this.torrentManager.addTorrent(file);     		
			this.displayTorrent(torrent);
    }
    
    public void addTorrent(String path) throws InvalidBEncodingException, IOException{
		Torrent torrent = this.torrentManager.addTorrent(path);     		
		this.displayTorrent(torrent);
}
    
}
